package org.smartercontext.contextmger.converters;

import java.util.HashMap;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.smartercontext.contextmger.contextsphere.ContextManagerController;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;

public class Formatter {

	public String applyFormat(Model usermodel , String format, String username) throws JSONException{
		
		ContextManagerController.contextManagerController();
		String nsUser="http://smartercontext.org/vocabularies/rdf/"+username+".rdf#";
		Resource user = usermodel.getResource(nsUser+username);
		
		if(format.equals("json")){
			
			JSONObject jsonobj = new JSONObject();
			
			StmtIterator iterator = user.listProperties();
			HashMap<Property, Integer> map = new HashMap<>();
			while(iterator.hasNext()){
			
				Statement stmt = iterator.next();
				Property predicate = stmt.getPredicate();
				RDFNode object = stmt.getObject();
				
				String propName = predicate.getLocalName();
				
				if(object.isLiteral()){
					String value = object.asLiteral().getString();
					jsonobj.put(propName, value);
				}
				
				if(object.isResource()){
					
					boolean contains = map.containsKey(predicate);
					if(contains){
						Integer quantity=map.get(predicate);
						quantity = quantity+new Integer(1);
						map.remove(predicate);
						map.put(predicate, quantity);
					}else{
						if(propName.equals("type")){
							jsonobj.put("type", stmt.getObject().toString().split("#")[1]);
						}else{
						map.put(predicate, new Integer(1));
						}
					}
					
				}
				
			}
			
			for(Entry<Property, Integer>e:map.entrySet()){
				Property prop = e.getKey();
				Integer value = e.getValue();
				
				int quantity = value.intValue();
				
				if(quantity>0){
					
					StmtIterator itProp = user.listProperties(prop);
					JSONArray array = new JSONArray();
					
					while(itProp.hasNext()){
						Statement stmt = itProp.next();
						String object = stmt.getObject().toString();
						
						JSONObject obj1 = new JSONObject();
						obj1.put(prop.getLocalName(), object.split("#")[1]);
						
						Resource resTemp = usermodel.getResource(object);
						updateJSONObject(usermodel,obj1, resTemp);
						array.put(obj1);
					}
					
					jsonobj.put(prop.getLocalName()+"_list", array);
					
				}
			}
			
			return jsonobj.toString();
		}		
		return "";
		
	}
	
	public JSONObject updateJSONObject(Model usermodel, JSONObject jsonobj, Resource resource) throws JSONException{
		
		HashMap<Property, Integer>map = new HashMap<>();
		
		StmtIterator iterator = resource.listProperties();
		while(iterator.hasNext()){
			Statement stmt = iterator.next();
			Property predicate = stmt.getPredicate();
			RDFNode object = stmt.getObject();
			
			String propName = predicate.getLocalName();
			
			if(object.isLiteral()){
				String value = object.asLiteral().getString();
				jsonobj.put(propName, value);
			}
			
			if(object.isResource()){
				
				boolean contains = map.containsKey(predicate);
				if(contains){
					Integer quantity=map.get(predicate);
					quantity = quantity+new Integer(1);
					map.remove(predicate);
					map.put(predicate, quantity);
				}else{
					if(propName.equals("type")){
						jsonobj.put("type", stmt.getObject().toString().split("#")[1]);
					}else{
					map.put(predicate, new Integer(1));
					}
				}
				
			}
			
		}
		
		for(Entry<Property, Integer>e:map.entrySet()){
			Property prop = e.getKey();
			Integer value = e.getValue();
			
			int quantity = value.intValue();
			
			if(quantity>0){
				
				StmtIterator itProp = resource.listProperties(prop);
				JSONArray array = new JSONArray();
				
				while(itProp.hasNext()){
					Statement stmt = itProp.next();
					String object = stmt.getObject().toString();
					
					JSONObject obj1 = new JSONObject();
					obj1.put(prop.getLocalName(), object.split("#")[1]);
					
					Resource resTemp = usermodel.getResource(object);
					updateJSONObject(usermodel,obj1, resTemp);
					array.put(obj1);
				}
				
				jsonobj.put(prop.getLocalName()+"_list", array);
				
			}
		}
		
		return jsonobj;
		
	}
}
